package socket

import (
	"api-gateway-core/auth"
	"api-gateway-core/mapping"
	"api-gateway-core/session"
	"api-gateway-core/socket/parser"
	"api-gateway-core/socket/parser/factory"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/evanphx/wildcat"
	"log"
	"net/http"
)

type httpCodec struct {
	parser  *wildcat.HTTPParser
	request *http.Request
	buf     []byte
}

// 添加错误信息
func (hc *httpCodec) appendFailInfo(err error) {
	resp := parser.BuildFailResp(err.Error())
	res, _ := json.Marshal(resp)
	//3. 返回信息
	hc.buf = append(hc.buf, fmt.Sprintf("\r\nContent-Length: %d\r\n\r\n%s", len(res), res)...)
}

// 处理HTTP信息
func (hc *httpCodec) handler(gatewaySessionFactory *session.GatewaySessionFactory) {
	log.Println("负载均衡到了：" + gatewaySessionFactory.Configuration.Port + "端口")
	//1. 解析HTTP请求信息
	method := hc.request.Method
	requestParse := factory.ReqParserFactory[mapping.HttpCommandType(method)]
	reqParserRes := requestParse.Parse(hc.request)
	InfoMap, err := reqParserRes.InfoMap, reqParserRes.Err
	if err != nil {
		hc.appendFailInfo(err)
		return
	}
	//2. 获取Uri
	uri := hc.request.URL.Path
	if uri == "/favicon.ico" {
		return
	}
	//3. 判断是否需要鉴权
	gatewaySession := gatewaySessionFactory.OpenSession(uri+"-"+method, InfoMap)
	if gatewaySession.Datasource.HttpStatement.IsAuth() {
		uId := hc.request.Header.Get("uId")
		token := hc.request.Header.Get("Authorization")
		verifyToken, err := auth.VerifyToken(token)
		if err != nil || verifyToken.UserID != uId {
			hc.appendFailInfo(errors.New("Token error:" + err.Error()))
			return
		}
	}
	//4. 泛化调用
	resp, err := gatewaySession.GetResult(InfoMap)
	if err != nil {
		hc.appendFailInfo(err)
		return
	}
	//5. 构造结果
	respResult := parser.BuildSuccessResp(resp)
	res, _ := json.Marshal(respResult)
	//6. 返回信息
	hc.buf = append(hc.buf, fmt.Sprintf("\r\nContent-Length: %d\r\n\r\n%s", len(res), res)...)
}

// 设置头信息返回
func (hc *httpCodec) appendResponseHeader() {
	hc.buf = append(hc.buf, "HTTP/1.1 200 OK"+
		"\r\nContent-Type: application/json; charset=UTF-8"+
		"\r\nConnection: keep-alive"+
		"\r\nAccess-Control-Allow-Origin: *"+
		"\r\nAccess-Control-Allow-Headers: *"+
		"\r\nAccess-Control-Allow-Methods: *"+
		"\r\nAccess-Control-Allow-Credentials: true"...)
}
